package com.gcmm.websocket;


import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.gcmm.json.JacksonObjectMapper;
import com.gcmm.pojo.MsgDTO;
import jakarta.websocket.*;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import com.gcmm.pojo.R;
import com.gcmm.pojo.User;


@Component
@Slf4j
@ServerEndpoint("/ws/chat/{userId}")
public class WebSocket {

    //与某个客户端的连接会话，需要通过它来给客户端发送数据
    private Session session;
    /**
     * 用户ID
     */
    private String userId;

    /**
     * 用来存放每个客户端对应的MyWebSocket对象。
     */
   // private static CopyOnWriteArraySet<WebSocket> webSockets =new CopyOnWriteArraySet<>();
    // 用来存在线连接用户信息
    private static ConcurrentHashMap<String,Session> sessionPool = new ConcurrentHashMap<String,Session>();
private static final JacksonObjectMapper objectMapper = new JacksonObjectMapper();
    /**
     * 链接成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session, @PathParam(value="userId")String userId) {
        try {
          //ring, String> pathParameters = session.getPathParameters();
           // log.info("map:{}",pathParameters.toString());
            log.info("session:{}",session.toString());
            Map<String, List<String>> requestParameterMap = session.getRequestParameterMap();
            String name = requestParameterMap.get("name").get(0);
            log.info("query{}",name);

            sessionPool.put(userId, session);
            R r = R.builder().type("join")
                    .user(User.builder()
                            .id(userId)
                            .userId(userId)
                            .name(name)
                            .msg("加入群聊")
                            .image("0")
                            .build()).build();

           String resultString = objectMapper.writeValueAsString(r);
           log.info("发送消息：{}",resultString  );
           sendAllMessage(resultString);

         //  session.getAsyncRemote().sendText();

//只有一个人能看到：session.getAsyncRemote().sendText(resultString);
        } catch (Exception e) {
        }
    }

    /**
     * 链接关闭调用的方法
     */
    @OnClose
    public void onClose(Session session) {

    }
    /**
     * 收到客户端消息后调用的方法
     *
     * @param message
     * @param message
     */
    @OnMessage
    public void onMessage(String message) throws JsonProcessingException {
        log.info("【websocket消息】收到客户端消息:"+message);
MsgDTO dto = objectMapper.readValue(message, MsgDTO.class);
      String toUserId = dto.getToId();
        String fromUserId = dto.getFromId();
        String msg = dto.getMessage();
        String type = dto.getType();

        if (type.equals("list")){
           Session newSession= sessionPool.get(toUserId);
            if (newSession != null&&newSession.isOpen()) {
                try {
                    newSession.getAsyncRemote().sendText(message);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return;
        }

        R r = R.builder().type(type).data(msg)
                .user(User.builder()
                        .id(dto.getUser().getId())
                        .userId(fromUserId)
                        .name(dto.getUser().getName())
                        .msg(msg)
                        .image("0")
                        .build()).build();

        Session session = sessionPool.get(fromUserId);
String resultString = objectMapper.writeValueAsString(r);
sendAllMessage(resultString);
                //session.getAsyncRemote().sendText(resultString);


/*
                Map<String,String> dto = objectMapper.readValue(message, Map.class);
        log.info("【websocket消息】收到客户端消息:"+dto);
        if (dto.get("type").equals("join")){
            sessionPool.put(dto.get("userId"), session);
        }
*/
    }

    /** 发送错误时的处理
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {

        log.error("用户错误,原因:"+error.getMessage());
        error.printStackTrace();
    }


    // 此为广播消息
    public void sendAllMessage(String message) {
        log.info("【websocket消息】广播消息:"+message);
        for (String userId : sessionPool.keySet()) {
            Session session = sessionPool.get(userId);
            if (session != null&&session.isOpen()) {
                try {
                    session.getAsyncRemote().sendText(message);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }



//        for(WebSocket webSocket : webSockets) {
//            try {
//                if(webSocket.session.isOpen()) {
//                    webSocket.session.getAsyncRemote().sendText(message);
//                }
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
//        }
    }

    // 此为单点消息
    public void sendOneMessage(String userId, String message) {
        Session session = sessionPool.get(userId);

        if (session != null&&session.isOpen()) {
            try {
                log.info("【websocket消息】 单点消息:"+message);
                session.getAsyncRemote().sendText(message);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    // 此为单点消息(多人)
    public void sendMoreMessage(String[] userIds, String message) {
        for(String userId:userIds) {
            Session session = sessionPool.get(userId);
            if (session != null&&session.isOpen()) {
                try {
                    log.info("【websocket消息】 单点消息:"+message);
                    session.getAsyncRemote().sendText(message);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

    }

}

